package com.cskaoyan.javase.oop3._2inner._6lambda._2notice;

/**
 * 关于Lambda表达式的注意事项：
 *      1.特殊的局部内部类，所以访问作用域内部的局部变量,这个局部变量应该是final修饰的
 *      2.(Lambda表达式的特殊点)
 *          Lambda表达式的"{}"是匿名子类实现抽象方法的方法体
 *          但是它没有自身独有的作用域
 *          和定义Lambda表达式的"{}"共用同一个作用域
 *      3.方法引用,是Lambda表达式的本质是实现了功能接口中的抽象方法
 *          这个方法实现,既可以直接写在Lambda表达式中
 *          也可以用Lambda表达式指向一个已经存在的方法
 *          这些已存在的方法可以自己手动定义
 *          也可以是一些JDK源码中的方法以及三方工具包中的方法
 *          JDK8当中,接口中引入了静态方法以及默认方法
 *          这些方法,在很大程度上是为了方便Lambda表达式的方法引用而定义的
 *
 * @since 09:23
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {

        int a = 10;
        IA ia = () -> {
            // 匿名子类实现抽象方法的方法体
            // Variable 'a' is already defined in the scope
            // int a = 100;

            System.out.println(a);
            // Variable used in lambda expression should be final or effectively final
            // a++;
        };
        /*
            匿名内部类有自身独有的作用域
            类体,方法体都是自身所独有的
         */
        new IA() {
            // 匿名子类的独有成员变量
            int a = 20;

            @Override
            public void test() {
                System.out.println(a);
                // a++;
                // 匿名子类成员方法中的局部变量
                int a = 30;
            }
        };

        IB ib = str -> System.out.println(str);
        ib.test("hello world!");

        IB ib2 = System.out::println;
        ib2.test("我喜欢你~");


    }
}

@FunctionalInterface
interface IB {
    void test(String str);
}

@FunctionalInterface
interface IA {
    void test();
}
